//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension Route53Profiles {
    // MARK: Enums

    public enum ProfileStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case complete = "COMPLETE"
        case creating = "CREATING"
        case deleted = "DELETED"
        case deleting = "DELETING"
        case failed = "FAILED"
        case updating = "UPDATING"
        public var description: String { return self.rawValue }
    }

    public enum ShareStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case notShared = "NOT_SHARED"
        case sharedByMe = "SHARED_BY_ME"
        case sharedWithMe = "SHARED_WITH_ME"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct AssociateProfileRequest: AWSEncodableShape {
        ///  A name for the association.
        public let name: String
        ///  ID of the Profile.
        public let profileId: String
        ///  The ID of the VPC.
        public let resourceId: String
        ///  A list of the tag keys and values that you want to identify the Profile association.
        public let tags: [Tag]?

        @inlinable
        public init(name: String, profileId: String, resourceId: String, tags: [Tag]? = nil) {
            self.name = name
            self.profileId = profileId
            self.resourceId = resourceId
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, pattern: "^(?!^[0-9]+$)([a-zA-Z0-9\\-_' ']+)$")
            try self.validate(self.profileId, name: "profileId", parent: name, max: 64)
            try self.validate(self.profileId, name: "profileId", parent: name, min: 1)
            try self.validate(self.resourceId, name: "resourceId", parent: name, max: 64)
            try self.validate(self.resourceId, name: "resourceId", parent: name, min: 1)
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case profileId = "ProfileId"
            case resourceId = "ResourceId"
            case tags = "Tags"
        }
    }

    public struct AssociateProfileResponse: AWSDecodableShape {
        ///  The association that you just created. The association has an ID that you can use to identify it in other requests, like update and delete.
        public let profileAssociation: ProfileAssociation?

        @inlinable
        public init(profileAssociation: ProfileAssociation? = nil) {
            self.profileAssociation = profileAssociation
        }

        private enum CodingKeys: String, CodingKey {
            case profileAssociation = "ProfileAssociation"
        }
    }

    public struct AssociateResourceToProfileRequest: AWSEncodableShape {
        ///  Name for the resource association.
        public let name: String
        ///  ID of the Profile.
        public let profileId: String
        ///  Amazon resource number, ARN, of the DNS resource.
        public let resourceArn: String
        ///  If you are adding a DNS Firewall rule group, include also a priority. The priority indicates the processing order for the rule groups, starting with the priority assinged the lowest value.
        ///  The allowed values for priority are between 100 and 9900.
        public let resourceProperties: String?

        @inlinable
        public init(name: String, profileId: String, resourceArn: String, resourceProperties: String? = nil) {
            self.name = name
            self.profileId = profileId
            self.resourceArn = resourceArn
            self.resourceProperties = resourceProperties
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, pattern: "^(?!^[0-9]+$)([a-zA-Z0-9\\-_' ']+)$")
            try self.validate(self.profileId, name: "profileId", parent: name, max: 64)
            try self.validate(self.profileId, name: "profileId", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 255)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case profileId = "ProfileId"
            case resourceArn = "ResourceArn"
            case resourceProperties = "ResourceProperties"
        }
    }

    public struct AssociateResourceToProfileResponse: AWSDecodableShape {
        ///  Infromation about the AssociateResourceToProfile, including a status message.
        public let profileResourceAssociation: ProfileResourceAssociation?

        @inlinable
        public init(profileResourceAssociation: ProfileResourceAssociation? = nil) {
            self.profileResourceAssociation = profileResourceAssociation
        }

        private enum CodingKeys: String, CodingKey {
            case profileResourceAssociation = "ProfileResourceAssociation"
        }
    }

    public struct CreateProfileRequest: AWSEncodableShape {
        ///  ClientToken is an idempotency token that ensures a call to CreateProfile completes only once. You choose the value to pass.  For example, an issue might prevent you from getting a response from CreateProfile.  In this case, safely retry your call to CreateProfile by using the same CreateProfile parameter value.
        public let clientToken: String
        ///  A name for the Profile.
        public let name: String
        ///  A list of the tag keys and values that you want to associate with the Route 53 Profile.
        public let tags: [Tag]?

        @inlinable
        public init(clientToken: String = CreateProfileRequest.idempotencyToken(), name: String, tags: [Tag]? = nil) {
            self.clientToken = clientToken
            self.name = name
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 255)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, pattern: "^(?!^[0-9]+$)([a-zA-Z0-9\\-_' ']+)$")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case name = "Name"
            case tags = "Tags"
        }
    }

    public struct CreateProfileResponse: AWSDecodableShape {
        ///  The Profile that you just created.
        public let profile: Profile?

        @inlinable
        public init(profile: Profile? = nil) {
            self.profile = profile
        }

        private enum CodingKeys: String, CodingKey {
            case profile = "Profile"
        }
    }

    public struct DeleteProfileRequest: AWSEncodableShape {
        ///  The ID of the Profile that you want to delete.
        public let profileId: String

        @inlinable
        public init(profileId: String) {
            self.profileId = profileId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.profileId, key: "ProfileId")
        }

        public func validate(name: String) throws {
            try self.validate(self.profileId, name: "profileId", parent: name, max: 64)
            try self.validate(self.profileId, name: "profileId", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteProfileResponse: AWSDecodableShape {
        ///  Information about the DeleteProfile request, including the status of the request.
        public let profile: Profile?

        @inlinable
        public init(profile: Profile? = nil) {
            self.profile = profile
        }

        private enum CodingKeys: String, CodingKey {
            case profile = "Profile"
        }
    }

    public struct DisassociateProfileRequest: AWSEncodableShape {
        ///  ID of the Profile.
        public let profileId: String
        ///  The ID of the VPC.
        public let resourceId: String

        @inlinable
        public init(profileId: String, resourceId: String) {
            self.profileId = profileId
            self.resourceId = resourceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.profileId, key: "ProfileId")
            request.encodePath(self.resourceId, key: "ResourceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.profileId, name: "profileId", parent: name, max: 64)
            try self.validate(self.profileId, name: "profileId", parent: name, min: 1)
            try self.validate(self.resourceId, name: "resourceId", parent: name, max: 64)
            try self.validate(self.resourceId, name: "resourceId", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DisassociateProfileResponse: AWSDecodableShape {
        ///  Information about the DisassociateProfile request.
        public let profileAssociation: ProfileAssociation?

        @inlinable
        public init(profileAssociation: ProfileAssociation? = nil) {
            self.profileAssociation = profileAssociation
        }

        private enum CodingKeys: String, CodingKey {
            case profileAssociation = "ProfileAssociation"
        }
    }

    public struct DisassociateResourceFromProfileRequest: AWSEncodableShape {
        ///  The ID of the Profile.
        public let profileId: String
        /// The Amazon Resource Name (ARN) of the resource.
        public let resourceArn: String

        @inlinable
        public init(profileId: String, resourceArn: String) {
            self.profileId = profileId
            self.resourceArn = resourceArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.profileId, key: "ProfileId")
            request.encodePath(self.resourceArn, key: "ResourceArn")
        }

        public func validate(name: String) throws {
            try self.validate(self.profileId, name: "profileId", parent: name, max: 64)
            try self.validate(self.profileId, name: "profileId", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 255)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DisassociateResourceFromProfileResponse: AWSDecodableShape {
        ///  Information about the DisassociateResourceFromProfile request, including the status of the request.
        public let profileResourceAssociation: ProfileResourceAssociation?

        @inlinable
        public init(profileResourceAssociation: ProfileResourceAssociation? = nil) {
            self.profileResourceAssociation = profileResourceAssociation
        }

        private enum CodingKeys: String, CodingKey {
            case profileResourceAssociation = "ProfileResourceAssociation"
        }
    }

    public struct GetProfileAssociationRequest: AWSEncodableShape {
        ///  The identifier of the association you want to get information about.
        public let profileAssociationId: String

        @inlinable
        public init(profileAssociationId: String) {
            self.profileAssociationId = profileAssociationId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.profileAssociationId, key: "ProfileAssociationId")
        }

        public func validate(name: String) throws {
            try self.validate(self.profileAssociationId, name: "profileAssociationId", parent: name, max: 64)
            try self.validate(self.profileAssociationId, name: "profileAssociationId", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetProfileAssociationResponse: AWSDecodableShape {
        ///  Information about the Profile association that you specified in a GetProfileAssociation request.
        public let profileAssociation: ProfileAssociation?

        @inlinable
        public init(profileAssociation: ProfileAssociation? = nil) {
            self.profileAssociation = profileAssociation
        }

        private enum CodingKeys: String, CodingKey {
            case profileAssociation = "ProfileAssociation"
        }
    }

    public struct GetProfileRequest: AWSEncodableShape {
        ///  ID of the Profile.
        public let profileId: String

        @inlinable
        public init(profileId: String) {
            self.profileId = profileId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.profileId, key: "ProfileId")
        }

        public func validate(name: String) throws {
            try self.validate(self.profileId, name: "profileId", parent: name, max: 64)
            try self.validate(self.profileId, name: "profileId", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetProfileResourceAssociationRequest: AWSEncodableShape {
        ///   The ID of the profile resource association that you want to get information about.
        public let profileResourceAssociationId: String

        @inlinable
        public init(profileResourceAssociationId: String) {
            self.profileResourceAssociationId = profileResourceAssociationId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.profileResourceAssociationId, key: "ProfileResourceAssociationId")
        }

        public func validate(name: String) throws {
            try self.validate(self.profileResourceAssociationId, name: "profileResourceAssociationId", parent: name, max: 64)
            try self.validate(self.profileResourceAssociationId, name: "profileResourceAssociationId", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetProfileResourceAssociationResponse: AWSDecodableShape {
        ///  Information about the Profile resource association that you specified in a GetProfileResourceAssociation request.
        public let profileResourceAssociation: ProfileResourceAssociation?

        @inlinable
        public init(profileResourceAssociation: ProfileResourceAssociation? = nil) {
            self.profileResourceAssociation = profileResourceAssociation
        }

        private enum CodingKeys: String, CodingKey {
            case profileResourceAssociation = "ProfileResourceAssociation"
        }
    }

    public struct GetProfileResponse: AWSDecodableShape {
        ///  Information about the Profile, including the status of the Profile.
        public let profile: Profile?

        @inlinable
        public init(profile: Profile? = nil) {
            self.profile = profile
        }

        private enum CodingKeys: String, CodingKey {
            case profile = "Profile"
        }
    }

    public struct InvalidParameterException: AWSErrorShape {
        ///  The parameter field name for the invalid parameter exception.
        public let fieldName: String?
        public let message: String

        @inlinable
        public init(fieldName: String? = nil, message: String) {
            self.fieldName = fieldName
            self.message = message
        }

        private enum CodingKeys: String, CodingKey {
            case fieldName = "FieldName"
            case message = "Message"
        }
    }

    public struct LimitExceededException: AWSErrorShape {
        public let message: String?
        ///  The resource type that caused the limits to be exceeded.
        public let resourceType: String?

        @inlinable
        public init(message: String? = nil, resourceType: String? = nil) {
            self.message = message
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "Message"
            case resourceType = "ResourceType"
        }
    }

    public struct ListProfileAssociationsRequest: AWSEncodableShape {
        ///  The maximum number of objects that you want to return for this request. If more objects are available, in the response,  a NextToken value, which you can use in a subsequent call to get the next batch of objects, is provided.  If you don't specify a value for MaxResults, up to 100 objects are returned.
        public let maxResults: Int?
        ///  For the first call to this list request, omit this value.
        ///  When you request a list of objects, at most the number of objects specified by MaxResults is returned.  If more objects are available for retrieval, a NextToken value is returned in the response.  To retrieve the next batch of objects, use the token that was returned for the prior request in your next request.
        public let nextToken: String?
        /// ID of the Profile.
        public let profileId: String?
        ///  ID of the VPC.
        public let resourceId: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, profileId: String? = nil, resourceId: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.profileId = profileId
            self.resourceId = resourceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodeQuery(self.profileId, key: "profileId")
            request.encodeQuery(self.resourceId, key: "resourceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.profileId, name: "profileId", parent: name, max: 64)
            try self.validate(self.profileId, name: "profileId", parent: name, min: 1)
            try self.validate(self.resourceId, name: "resourceId", parent: name, max: 64)
            try self.validate(self.resourceId, name: "resourceId", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListProfileAssociationsResponse: AWSDecodableShape {
        ///  If more than MaxResults profile associations match the specified criteria, you can submit another  ListProfileAssociations request to get the next group of results. In the next request, specify the value of NextToken from the previous response.
        public let nextToken: String?
        ///  A complex type that containts settings information about the profile's VPC associations.
        public let profileAssociations: [ProfileAssociation]?

        @inlinable
        public init(nextToken: String? = nil, profileAssociations: [ProfileAssociation]? = nil) {
            self.nextToken = nextToken
            self.profileAssociations = profileAssociations
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case profileAssociations = "ProfileAssociations"
        }
    }

    public struct ListProfileResourceAssociationsRequest: AWSEncodableShape {
        ///  The maximum number of objects that you want to return for this request. If more objects are available, in the response,  a NextToken value, which you can use in a subsequent call to get the next batch of objects, is provided.  If you don't specify a value for MaxResults, up to 100 objects are returned.
        public let maxResults: Int?
        ///  For the first call to this list request, omit this value.  When you request a list of objects, at most the number of objects specified by MaxResults is returned.  If more objects are available for retrieval, a NextToken value is returned in the response.  To retrieve the next batch of objects, use the token that was returned for the prior request in your next request.
        public let nextToken: String?
        /// The ID of the Profile.
        public let profileId: String
        ///  ID of a resource if you want information on only one type.
        public let resourceType: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, profileId: String, resourceType: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.profileId = profileId
            self.resourceType = resourceType
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodePath(self.profileId, key: "ProfileId")
            request.encodeQuery(self.resourceType, key: "resourceType")
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.profileId, name: "profileId", parent: name, max: 64)
            try self.validate(self.profileId, name: "profileId", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListProfileResourceAssociationsResponse: AWSDecodableShape {
        ///  If more than MaxResults resource associations match the specified criteria, you can submit another  ListProfileResourceAssociations request to get the next group of results. In the next request, specify the value of NextToken from the previous response.
        public let nextToken: String?
        ///  Information about the profile resource association that you specified in a GetProfileResourceAssociation request.
        public let profileResourceAssociations: [ProfileResourceAssociation]?

        @inlinable
        public init(nextToken: String? = nil, profileResourceAssociations: [ProfileResourceAssociation]? = nil) {
            self.nextToken = nextToken
            self.profileResourceAssociations = profileResourceAssociations
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case profileResourceAssociations = "ProfileResourceAssociations"
        }
    }

    public struct ListProfilesRequest: AWSEncodableShape {
        ///  The maximum number of objects that you want to return for this request. If more objects are available, in the response,  a NextToken value, which you can use in a subsequent call to get the next batch of objects, is provided.  If you don't specify a value for MaxResults, up to 100 objects are returned.
        public let maxResults: Int?
        ///  For the first call to this list request, omit this value.  When you request a list of objects, at most the number of objects specified by MaxResults is returned.  If more objects are available for retrieval, a NextToken value is returned in the response.  To retrieve the next batch of objects, use the token that was returned for the prior request in your next request.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListProfilesResponse: AWSDecodableShape {
        ///  If more than MaxResults resource associations match the specified criteria, you can submit another  ListProfiles request to get the next group of results. In the next request, specify the value of NextToken from the previous response.
        public let nextToken: String?
        ///  Summary information about the Profiles.
        public let profileSummaries: [ProfileSummary]?

        @inlinable
        public init(nextToken: String? = nil, profileSummaries: [ProfileSummary]? = nil) {
            self.nextToken = nextToken
            self.profileSummaries = profileSummaries
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case profileSummaries = "ProfileSummaries"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        ///  The Amazon Resource Name (ARN) for the resource that you want to list the tags for.
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "ResourceArn")
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 255)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        ///  The tags that are associated with the resource that you specified in the ListTagsForResource request.
        public let tags: [String: String]

        @inlinable
        public init(tags: [String: String]) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct Profile: AWSDecodableShape {
        ///  The Amazon Resource Name (ARN) of the Profile.
        public let arn: String?
        ///  The ClientToken value that was assigned when the Profile was created.
        public let clientToken: String?
        ///  The date and time that the Profile was created, in Unix time format and Coordinated Universal Time (UTC).
        public let creationTime: Date?
        /// ID of the Profile.
        public let id: String?
        ///  The date and time that the Profile was modified, in Unix time format and Coordinated Universal Time (UTC).
        public let modificationTime: Date?
        /// Name of the Profile.
        public let name: String?
        ///  Amazon Web Services account ID of the Profile owner.
        public let ownerId: String?
        ///  Sharing status for the Profile.
        public let shareStatus: ShareStatus?
        ///  The status for the Profile.
        public let status: ProfileStatus?
        ///  Status message that includes additiona information about the Profile.
        public let statusMessage: String?

        @inlinable
        public init(arn: String? = nil, clientToken: String? = nil, creationTime: Date? = nil, id: String? = nil, modificationTime: Date? = nil, name: String? = nil, ownerId: String? = nil, shareStatus: ShareStatus? = nil, status: ProfileStatus? = nil, statusMessage: String? = nil) {
            self.arn = arn
            self.clientToken = clientToken
            self.creationTime = creationTime
            self.id = id
            self.modificationTime = modificationTime
            self.name = name
            self.ownerId = ownerId
            self.shareStatus = shareStatus
            self.status = status
            self.statusMessage = statusMessage
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case clientToken = "ClientToken"
            case creationTime = "CreationTime"
            case id = "Id"
            case modificationTime = "ModificationTime"
            case name = "Name"
            case ownerId = "OwnerId"
            case shareStatus = "ShareStatus"
            case status = "Status"
            case statusMessage = "StatusMessage"
        }
    }

    public struct ProfileAssociation: AWSDecodableShape {
        ///  The date and time that the Profile association was created, in Unix time format and Coordinated Universal Time (UTC).
        public let creationTime: Date?
        ///  ID of the Profile association.
        public let id: String?
        ///  The date and time that the Profile association was modified, in Unix time format and Coordinated Universal Time (UTC).
        public let modificationTime: Date?
        ///  Name of the Profile association.
        public let name: String?
        ///  Amazon Web Services account ID of the Profile association owner.
        public let ownerId: String?
        /// ID of the Profile.
        public let profileId: String?
        ///  The Amazon Resource Name (ARN) of the VPC.
        public let resourceId: String?
        ///  Status of the Profile association.
        public let status: ProfileStatus?
        ///  Additional information about the Profile association.
        public let statusMessage: String?

        @inlinable
        public init(creationTime: Date? = nil, id: String? = nil, modificationTime: Date? = nil, name: String? = nil, ownerId: String? = nil, profileId: String? = nil, resourceId: String? = nil, status: ProfileStatus? = nil, statusMessage: String? = nil) {
            self.creationTime = creationTime
            self.id = id
            self.modificationTime = modificationTime
            self.name = name
            self.ownerId = ownerId
            self.profileId = profileId
            self.resourceId = resourceId
            self.status = status
            self.statusMessage = statusMessage
        }

        private enum CodingKeys: String, CodingKey {
            case creationTime = "CreationTime"
            case id = "Id"
            case modificationTime = "ModificationTime"
            case name = "Name"
            case ownerId = "OwnerId"
            case profileId = "ProfileId"
            case resourceId = "ResourceId"
            case status = "Status"
            case statusMessage = "StatusMessage"
        }
    }

    public struct ProfileResourceAssociation: AWSDecodableShape {
        ///  The date and time that the Profile resource association was created, in Unix time format and Coordinated Universal Time (UTC).
        public let creationTime: Date?
        ///  ID of the Profile resource association.
        public let id: String?
        ///  The date and time that the Profile resource association was modified, in Unix time format and Coordinated Universal Time (UTC).
        public let modificationTime: Date?
        ///  Name of the Profile resource association.
        public let name: String?
        ///  Amazon Web Services account ID of the Profile resource association owner.
        public let ownerId: String?
        ///  Profile ID of the Profile that the resources are associated with.
        public let profileId: String?
        ///  The Amazon Resource Name (ARN) of the resource association.
        public let resourceArn: String?
        ///  If the DNS resource is a DNS Firewall rule group, this indicates the priority.
        public let resourceProperties: String?
        ///  Resource type, such as a private hosted zone, or DNS Firewall rule group.
        public let resourceType: String?
        ///  Status of the Profile resource association.
        public let status: ProfileStatus?
        ///  Additional information about the Profile resource association.
        public let statusMessage: String?

        @inlinable
        public init(creationTime: Date? = nil, id: String? = nil, modificationTime: Date? = nil, name: String? = nil, ownerId: String? = nil, profileId: String? = nil, resourceArn: String? = nil, resourceProperties: String? = nil, resourceType: String? = nil, status: ProfileStatus? = nil, statusMessage: String? = nil) {
            self.creationTime = creationTime
            self.id = id
            self.modificationTime = modificationTime
            self.name = name
            self.ownerId = ownerId
            self.profileId = profileId
            self.resourceArn = resourceArn
            self.resourceProperties = resourceProperties
            self.resourceType = resourceType
            self.status = status
            self.statusMessage = statusMessage
        }

        private enum CodingKeys: String, CodingKey {
            case creationTime = "CreationTime"
            case id = "Id"
            case modificationTime = "ModificationTime"
            case name = "Name"
            case ownerId = "OwnerId"
            case profileId = "ProfileId"
            case resourceArn = "ResourceArn"
            case resourceProperties = "ResourceProperties"
            case resourceType = "ResourceType"
            case status = "Status"
            case statusMessage = "StatusMessage"
        }
    }

    public struct ProfileSummary: AWSDecodableShape {
        ///  The Amazon Resource Name (ARN) of the Profile.
        public let arn: String?
        ///  ID of the Profile.
        public let id: String?
        ///  Name of the Profile.
        public let name: String?
        ///  Share status of the Profile.
        public let shareStatus: ShareStatus?

        @inlinable
        public init(arn: String? = nil, id: String? = nil, name: String? = nil, shareStatus: ShareStatus? = nil) {
            self.arn = arn
            self.id = id
            self.name = name
            self.shareStatus = shareStatus
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case id = "Id"
            case name = "Name"
            case shareStatus = "ShareStatus"
        }
    }

    public struct ResourceExistsException: AWSErrorShape {
        public let message: String?
        ///  The resource type that caused the resource exists exception.
        public let resourceType: String?

        @inlinable
        public init(message: String? = nil, resourceType: String? = nil) {
            self.message = message
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "Message"
            case resourceType = "ResourceType"
        }
    }

    public struct ResourceNotFoundException: AWSErrorShape {
        public let message: String?
        ///  The resource type that caused the resource not found exception.
        public let resourceType: String?

        @inlinable
        public init(message: String? = nil, resourceType: String? = nil) {
            self.message = message
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "Message"
            case resourceType = "ResourceType"
        }
    }

    public struct Tag: AWSEncodableShape {
        ///  Key associated with the Tag.
        public let key: String
        /// Value for the Tag.
        public let value: String

        @inlinable
        public init(key: String, value: String) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.value, name: "value", parent: name, max: 256)
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        ///  The Amazon Resource Name (ARN) for the resource that you want to add tags to.
        public let resourceArn: String
        ///  The tags that you want to add to the specified resource.
        public let tags: [String: String]

        @inlinable
        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "ResourceArn")
            try container.encode(self.tags, forKey: .tags)
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 255)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        ///  The Amazon Resource Name (ARN) for the resource that you want to remove tags from.
        public let resourceArn: String
        ///  The tags that you want to remove to the specified resource.
        public let tagKeys: [String]

        @inlinable
        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "ResourceArn")
            request.encodeQuery(self.tagKeys, key: "tagKeys")
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 255)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 200)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateProfileResourceAssociationRequest: AWSEncodableShape {
        /// Name of the resource association.
        public let name: String?
        /// ID of the resource association.
        public let profileResourceAssociationId: String
        ///  If you are adding a DNS Firewall rule group, include also a priority. The priority indicates the processing order for the rule groups, starting with the priority assinged the lowest value.  The allowed values for priority are between 100 and 9900.
        public let resourceProperties: String?

        @inlinable
        public init(name: String? = nil, profileResourceAssociationId: String, resourceProperties: String? = nil) {
            self.name = name
            self.profileResourceAssociationId = profileResourceAssociationId
            self.resourceProperties = resourceProperties
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.name, forKey: .name)
            request.encodePath(self.profileResourceAssociationId, key: "ProfileResourceAssociationId")
            try container.encodeIfPresent(self.resourceProperties, forKey: .resourceProperties)
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 64)
            try self.validate(self.name, name: "name", parent: name, pattern: "^(?!^[0-9]+$)([a-zA-Z0-9\\-_' ']+)$")
            try self.validate(self.profileResourceAssociationId, name: "profileResourceAssociationId", parent: name, max: 64)
            try self.validate(self.profileResourceAssociationId, name: "profileResourceAssociationId", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case resourceProperties = "ResourceProperties"
        }
    }

    public struct UpdateProfileResourceAssociationResponse: AWSDecodableShape {
        ///  Information about the UpdateProfileResourceAssociation request, including a status message.
        public let profileResourceAssociation: ProfileResourceAssociation?

        @inlinable
        public init(profileResourceAssociation: ProfileResourceAssociation? = nil) {
            self.profileResourceAssociation = profileResourceAssociation
        }

        private enum CodingKeys: String, CodingKey {
            case profileResourceAssociation = "ProfileResourceAssociation"
        }
    }
}

// MARK: - Errors

/// Error enum for Route53Profiles
public struct Route53ProfilesErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case internalServiceErrorException = "InternalServiceErrorException"
        case invalidNextTokenException = "InvalidNextTokenException"
        case invalidParameterException = "InvalidParameterException"
        case limitExceededException = "LimitExceededException"
        case resourceExistsException = "ResourceExistsException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize Route53Profiles
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    ///  The current account doesn't have the IAM permissions required to perform the specified operation.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// The request you submitted conflicts with an existing request.
    public static var conflictException: Self { .init(.conflictException) }
    /// An internal server error occured. Retry your request.
    public static var internalServiceErrorException: Self { .init(.internalServiceErrorException) }
    /// The NextToken you provided isn;t valid.
    public static var invalidNextTokenException: Self { .init(.invalidNextTokenException) }
    ///  One or more parameters in this request are not valid.
    public static var invalidParameterException: Self { .init(.invalidParameterException) }
    ///  The request caused one or more limits to be exceeded.
    public static var limitExceededException: Self { .init(.limitExceededException) }
    ///  The resource you are trying to associate, has already been associated.
    public static var resourceExistsException: Self { .init(.resourceExistsException) }
    /// The resource you are associating is not found.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    ///  The request was throttled. Try again in a few minutes.
    public static var throttlingException: Self { .init(.throttlingException) }
    ///  You have provided an invalid command.
    public static var validationException: Self { .init(.validationException) }
}

extension Route53ProfilesErrorType: AWSServiceErrorType {
    public static let errorCodeMap: [String: AWSErrorShape.Type] = [
        "InvalidParameterException": Route53Profiles.InvalidParameterException.self,
        "LimitExceededException": Route53Profiles.LimitExceededException.self,
        "ResourceExistsException": Route53Profiles.ResourceExistsException.self,
        "ResourceNotFoundException": Route53Profiles.ResourceNotFoundException.self
    ]
}

extension Route53ProfilesErrorType: Equatable {
    public static func == (lhs: Route53ProfilesErrorType, rhs: Route53ProfilesErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension Route53ProfilesErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
